#include "TcpConnection.h"
#include "SubReactor.h"
#include <iostream>
#include <sstream>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/tcp.h>

using std::cout;
using std::endl;
using std::cerr;
using std::ostringstream;

TcpConnection::TcpConnection(int fd, EventLoop *loop)
: _sockIO(fd)
, _sock(fd)
, _lAddr(getLocalAddr())
, _pAddr(getPeerAddr())
, _loop(loop)
, _reactor(nullptr)
{
    // 设置TCP_NODELAY，禁用Nagle算法，确保数据立即发送
    int flag = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
}

TcpConnection::TcpConnection(int fd, SubReactor *reactor)
: _sockIO(fd)
, _sock(fd)
, _lAddr(getLocalAddr())
, _pAddr(getPeerAddr())
, _loop(nullptr)
, _reactor(reactor)
{
    // 设置TCP_NODELAY，禁用Nagle算法，确保数据立即发送
    int flag = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
}

TcpConnection::~TcpConnection()
{

}

void TcpConnection::send(const string &msg)
{
    /* _sockIO.writen(msg.c_str(), msg.size()); */
    _sockIO.writeToBuffer(msg);
    _sockIO.flushBuffer();
}

string TcpConnection::receive()
{
    /* char buf[65535] = {0}; */
    /* _sockIO.readLine(buf, sizeof(buf)); */
    _sockIO.readToBuffer();
    /* return string(buf); */
    return _sockIO.readAllFromBuffer();
}

string TcpConnection::toString()
{
    ostringstream oss;
    oss << _lAddr.ip() << ":" << _lAddr.port()<< "----->" 
        << _pAddr.ip() << ":" << _pAddr.port();
    return oss.str();
}

InetAddr TcpConnection::getLocalAddr()
{
    struct sockaddr_in localaddr;
    socklen_t len = sizeof(localaddr);
    int ret = getsockname(_sock.fd(), (struct sockaddr*)&localaddr, &len);
    if(ret == -1)
    {
        cerr << "getsockname" << endl;
    }
    return InetAddr(localaddr);

}

InetAddr TcpConnection::getPeerAddr()
{
    struct sockaddr_in peeraddr;
    socklen_t len = sizeof(peeraddr);
    int ret = getpeername(_sock.fd(), (struct sockaddr*)&peeraddr, &len);
    if(ret == -1)
    {
        cerr << "getpeername" << endl;
    }
    return InetAddr(peeraddr);
}

bool TcpConnection::isClose() const
{
    // 使用socket选项检查连接状态，更可靠
    int error = 0;
    socklen_t len = sizeof(error);
    int ret = getsockopt(_sock.fd(), SOL_SOCKET, SO_ERROR, &error, &len);
    
    if (ret < 0) {
        return true;  // getsockopt失败，认为连接已关闭
    }
    
    if (error != 0) {
        return true;  // socket有错误，连接异常
    }
    
    // 进一步检查：尝试用MSG_PEEK检查数据
    char buf[1];
    int peek_ret = recv(_sock.fd(), buf, 1, MSG_PEEK | MSG_DONTWAIT);
    
    if (peek_ret == 0) {
        return true;  // 连接确实已关闭
    } else if (peek_ret < 0) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            return false;  // 暂时无数据，连接正常
        } else {
            return true;  // 其他错误，认为连接有问题
        }
    }
    
    return false;  // 有数据可读，连接正常
}

void TcpConnection::setNewConnectionCallback(const TcpConnectionCallback &cb)
{
    _onNewConnection = cb;
}

void TcpConnection::setMessageCallback(const TcpConnectionCallback &cb)
{
    _onMessage = cb;
}

void TcpConnection::setCloseCallback(const TcpConnectionCallback &cb)
{
    _onClose = cb;
}

void TcpConnection::handleNewConnectionCallback()
{
    if(_onNewConnection)
    {
        _onNewConnection(shared_from_this());
    }
    else
    {
        cout << "_onNewConnection == nullptr" << endl;
    }
}

void TcpConnection::handleMessageCallback()
{
    if(_onMessage)
    {
        _onMessage(shared_from_this());
    }
    else
    {
        cout << "_onMessage == nullptr" << endl;
    }
}

void TcpConnection::handleCloseCallback()
{ 
    if(_onClose)
    {
        _onClose(shared_from_this());
    }
    else
    {
        cout << "_onClose == nullptr" << endl;
    }
}

void TcpConnection::sendInLoop(const string &msg)
{
    // cout << "[TcpConnection] sendInLoop: _reactor=" << _reactor << ", _loop=" << _loop << endl;
    
    // 确保消息发送在连接所属的线程中执行
    if (_reactor) {
        // cout << "[TcpConnection] 使用SubReactor runInLoop" << endl;
        auto self = shared_from_this();
        _reactor->runInLoop([self, msg]() {
            // 在SubReactor线程中执行实际的发送
            /* cout << "[TcpConnection] 在SubReactor线程中执行send" << endl; */
            self->send(msg);
        });
    // } else if (_loop) {
    //     cout << "[TcpConnection] 使用EventLoop runInLoop" << endl;
    //     auto self = shared_from_this();
    //     _loop->runInLoop([self, msg]() {
    //         // 在EventLoop线程中执行实际的发送
    //         cout << "[TcpConnection] 在EventLoop线程中执行send" << endl;
    //         self->send(msg);
    //     });
    } else {
        // cout << "[TcpConnection] 直接发送（兜底）" << endl;
        // 兜底：直接发送
        send(msg);
    }
}
